package com.kate.mall.oauth.service;

import cn.hutool.core.map.MapUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kate.mall.common.utils.ListMap2VoUtil;
import com.kate.mall.common.utils.R;
import com.kate.mall.oauth.dto.ClientDto;
import com.kate.mall.oauth.feign.MemeberFeignClient;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.NoSuchClientException;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@Service
public class ClientDetailsServiceImpl implements ClientDetailsService {

    @Autowired
    private MemeberFeignClient memeberFeignClient;
    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private ListMap2VoUtil listMap2VoUtil;

    @Resource
    private ApplicationContext context;

    @Resource
    ObjectMapper objectMapper;

    @Override
    @SneakyThrows
    public ClientDetails loadClientByClientId(String clientId) {
        try {

            R clientDetailR = memeberFeignClient.getClientDetail(clientId);
            List<Map> clientDetailListMap = MapUtil.get((Map) clientDetailR.get("page"), "list", List.class);
            List<ClientDto> clientDtoList =listMap2VoUtil.<ClientDto>map2vo(clientDetailListMap, ClientDto.class);
            clientDtoList = objectMapper.convertValue(clientDtoList,new TypeReference<List<ClientDto>>(){});
            if (clientDtoList != null || clientDtoList.size() > 0) {
                ClientDto clientDto = clientDtoList.get(0);
                BaseClientDetails clientDetails = new BaseClientDetails(
                        clientDto.getClientId(),
                        clientDto.getResourceIds(),
                        clientDto.getScope(),
                        clientDto.getAuthorizedGrantTypes(),
                        clientDto.getAuthorities(),
                        clientDto.getWebServerRedirectUri()
                );
                clientDetails.setClientSecret(clientDto.getClientSecret());
                clientDetails.setAccessTokenValiditySeconds(clientDto.getAccessTokenValidity());
                clientDetails.setRefreshTokenValiditySeconds(clientDto.getRefreshTokenValidity());
                return clientDetails;
            } else {
                throw new NoSuchClientException("No client with requested id: " + clientId);
            }
        } catch (EmptyResultDataAccessException var4) {
            throw new NoSuchClientException("No client with requested id: " + clientId);
        }
    }
}